const loaderUtils = require('loader-utils');

const _propListMatcher = require('./prop-list-matcher.js');

const defaultopts = {
    enabled: true,
    matchTemplate: false,
    viewport: 1920,
    unit: 'vw',
    fixed: 5,
    propList: ['*'],
    minPixelValue: 1,
}

const template = /<template>([\s\S]+)<\/template>/gi
const ZPXRegExp = /\b(\d+(\.\d+)?)px\b/;
const PROP_PXRegExp = /\b([a-zA-Z-]+)\s*:\s*(\d+(\.\d+)?)px\b/;


module.exports = function (source) {
    let opts = loaderUtils.getOptions(this) || {};
    let config = Object.assign({}, defaultopts, opts);

    let pxGlobalRegExp = new RegExp(ZPXRegExp.source, 'g');
    let propPxGlobalRegExp = new RegExp(PROP_PXRegExp.source, 'g');

    let satisfyPropList = (0, _propListMatcher.createPropListMatcher)(config.propList)

    if (this.cacheable) {
        this.cacheable();
    }

    if (!config.enabled) {
        return source
    }

    let callback = (match, $1) => {
        if (!$1 || $1 < config.minPixelValue) return match
        let val = $1 / config.viewport * 100
        val = parseFloat(val.toFixed(config.fixed))
        return val === 0 ? val : val + config.unit
    }

    let propCallback = (match, $1, $2) => {
        if (satisfyPropList($1)) {
            if (!$2 || $2 < config.minPixelValue) return match
            let val = $2 / config.viewport * 100;
            val = parseFloat(val.toFixed(config.fixed))
            return `${$1}: ${val === 0 ? val : val + config.unit}`
        }
        return match
    }


    if (config.matchTemplate) {
        let _source = ''
        if (template.test(source)) {
            _source = source.match(template)[0]
        }

        let t_source = source
        if (propPxGlobalRegExp.test(_source)) {
            let $_source = _source.replace(propPxGlobalRegExp, propCallback)
            t_source = t_source.replace(template, $_source)
        }
        if (pxGlobalRegExp.test(_source)) {
            let $_source = _source.replace(pxGlobalRegExp, callback)
            t_source = t_source.replace(template, $_source)
        }
        return t_source
    } else if (propPxGlobalRegExp.test(source) || pxGlobalRegExp.test(source)) {
        let t_source = source
        if (propPxGlobalRegExp.test(source)) {
            t_source = t_source.replace(propPxGlobalRegExp, propCallback)
        }
        if (pxGlobalRegExp.test(source)) {
            t_source = t_source.replace(pxGlobalRegExp, callback)
        }
        return t_source
    } else {
        return source
    }
}

